/**
 * 弹窗封装类
 * 基于 OpenLayers Overlay 实现的地图弹窗
 */

import { Overlay } from 'ol';
import { Map as OlMap } from 'ol';
import { Coordinate } from '../types';
import { DataUtil } from '../utils/data';
import { EventEmitter } from '../utils/event';

/**
 * 弹窗配置选项
 */
export interface PopupOptions {
  /** 弹窗ID */
  id?: string;
  /** 是否自动定位（跟随地图移动） */
  autoPan?: boolean;
  /** 自动定位动画配置 */
  autoPanAnimation?: {
    duration?: number;
  };
  /** 自动定位边距 */
  autoPanMargin?: number;
  /** 弹窗位置偏移 [x, y] */
  offset?: [number, number];
  /** 弹窗定位方式 */
  positioning?: 'bottom-left' | 'bottom-center' | 'bottom-right' | 'center-left' | 'center-center' | 'center-right' | 'top-left' | 'top-center' | 'top-right';
  /** 是否在关闭时自动移除 */
  autoClose?: boolean;
  /** 是否显示关闭按钮 */
  showCloseButton?: boolean;
  /** 弹窗类名 */
  className?: string;
}

/**
 * 弹窗类
 */
export class Popup extends EventEmitter {
  /** OpenLayers Overlay 实例 */
  private overlay: Overlay | null = null;
  /** 弹窗容器元素 */
  private element: HTMLElement | null = null;
  /** 弹窗配置 */
  private options: PopupOptions;
  /** 是否已显示 */
  private isVisible: boolean = false;
  /** 当前坐标 */
  private currentCoordinate: Coordinate | null = null;

  /**
   * 构造函数
   * @param options 弹窗配置
   */
  constructor(options: PopupOptions = {}) {
    super();
    this.options = {
      autoPan: true,
      autoPanAnimation: { duration: 250 },
      autoPanMargin: 20,
      offset: [0, -10],
      positioning: 'bottom-center',
      autoClose: true,
      showCloseButton: true,
      className: 'zss-ol-popup',
      ...options
    };
    this.createElement();
  }

  /**
   * 创建弹窗元素
   */
  private createElement(): void {
    this.element = document.createElement('div');
    this.element.className = this.options.className || 'zss-ol-popup';
    this.element.style.cssText = `
      position: absolute;
      background: white;
      box-shadow: 0 2px 8px rgba(0,0,0,0.15);
      border-radius: 4px;
      padding: 12px;
      min-width: 200px;
      max-width: 400px;
      z-index: 1000;
    `;

    // 创建关闭按钮
    if (this.options.showCloseButton) {
      const closeButton = document.createElement('button');
      closeButton.innerHTML = '×';
      closeButton.style.cssText = `
        position: absolute;
        top: 4px;
        right: 4px;
        background: none;
        border: none;
        font-size: 20px;
        cursor: pointer;
        color: #666;
        width: 24px;
        height: 24px;
        line-height: 24px;
        padding: 0;
      `;
      closeButton.onclick = () => {
        this.close();
      };
      this.element.appendChild(closeButton);
    }

    // 创建内容容器
    const content = document.createElement('div');
    content.className = 'zss-ol-popup-content';
    this.element.appendChild(content);

    // 创建 Overlay
    this.overlay = new Overlay({
      element: this.element,
      autoPan: this.options.autoPan ? {
        animation: this.options.autoPanAnimation,
        margin: this.options.autoPanMargin
      } : false,
      offset: this.options.offset,
      positioning: this.options.positioning as any
    });
  }

  /**
   * 设置内容
   * @param content HTML 字符串或 DOM 元素
   */
  setContent(content: string | HTMLElement): void {
    if (!this.element) return;

    const contentEl = this.element.querySelector('.zss-ol-popup-content');
    if (contentEl) {
      if (typeof content === 'string') {
        contentEl.innerHTML = content;
      } else {
        contentEl.innerHTML = '';
        contentEl.appendChild(content);
      }
      this.emit('contentchange', content);
    }
  }

  /**
   * 获取内容
   * @returns 内容元素
   */
  getContent(): HTMLElement | null {
    if (!this.element) return null;
    return this.element.querySelector('.zss-ol-popup-content') as HTMLElement;
  }

  /**
   * 显示弹窗
   * @param map 地图实例
   * @param coordinate 坐标
   */
  show(map: OlMap, coordinate: Coordinate): void {
    if (!this.overlay || !this.element) return;

    this.currentCoordinate = coordinate;
    const olCoord = DataUtil.toOlCoordinate(coordinate);
    this.overlay.setPosition(olCoord);
    map.addOverlay(this.overlay);
    this.isVisible = true;
    this.emit('show', coordinate);
  }

  /**
   * 关闭弹窗
   */
  close(): void {
    if (!this.overlay) return;

    const map = this.overlay.getMap();
    if (map) {
      map.removeOverlay(this.overlay);
    }
    this.overlay.setPosition(undefined);
    this.isVisible = false;
    this.emit('close');
  }

  /**
   * 更新位置
   * @param coordinate 新坐标
   */
  setPosition(coordinate: Coordinate): void {
    if (!this.overlay) return;

    this.currentCoordinate = coordinate;
    const olCoord = DataUtil.toOlCoordinate(coordinate);
    this.overlay.setPosition(olCoord);
    this.emit('positionchange', coordinate);
  }

  /**
   * 获取位置
   * @returns 当前坐标
   */
  getPosition(): Coordinate | null {
    return this.currentCoordinate;
  }

  /**
   * 是否可见
   * @returns 是否可见
   */
  isOpen(): boolean {
    return this.isVisible;
  }

  /**
   * 设置样式
   * @param styles CSS 样式对象
   */
  setStyle(styles: Partial<CSSStyleDeclaration>): void {
    if (!this.element) return;

    Object.assign(this.element.style, styles);
  }

  /**
   * 获取 OpenLayers Overlay 实例
   * @returns Overlay 实例
   */
  getOverlay(): Overlay | null {
    return this.overlay;
  }

  /**
   * 获取弹窗ID
   * @returns 弹窗ID
   */
  getId(): string | undefined {
    return this.options.id;
  }

  /**
   * 销毁弹窗
   */
  destroy(): void {
    this.close();
    if (this.element) {
      this.element.remove();
      this.element = null;
    }
    this.overlay = null;
    this.removeAllListeners();
    this.emit('destroy');
  }
}

